package utils;

import java.awt.*;

/**
 * Filtr medianowy 3x3
 */
public class FullMedianFilter extends FilterBase
{

    protected int maskSize = 3;

    public void initializeFilter(int maskSize) throws Exception
    {
        if (maskSize % 2 == 0)
        {
            throw new Exception("Rozmiar maski musi być nieparzysty.");
        }
        this.maskSize = maskSize;
    }

    private int fullMedian(int[] a, int[] r, int[] g, int[] b)
    {
        int result = 0;
        result += (MonoMedianFilter.monoMedian(a) << 24);
        result += (MonoMedianFilter.monoMedian(r) << 16);
        result += (MonoMedianFilter.monoMedian(g) << 8);
        result += (MonoMedianFilter.monoMedian(b));
        if (true)
        {
            return result;
        }

        int sum, index = 0, min = Integer.MAX_VALUE;

        for (int i = 0; i < maskSize; i++)
        {
            sum = 0;
            for (int j = 0; j < maskSize; j++)
            {
                sum += Math.abs(r[i] - r[j]);
                sum += Math.abs(g[i] - g[j]);
                sum += Math.abs(b[i] - b[j]);
            }
            if (sum < min)
            {
                min = sum;
                index = i;
            }
        }
        return index;
    }

    protected int[] filterPixels(int width, int height, int[] inPixels, Rectangle transformedSpace)
    {
        int index = 0;
        int maskSqr = maskSize * maskSize;
        int maskBounds = maskSize / 2;
        int[] a = new int[maskSqr];
        int[] r = new int[maskSqr];
        int[] g = new int[maskSqr];
        int[] b = new int[maskSqr];
        int[] outPixels = new int[width * height];

        for (int y = 0; y < height; y++)
        {
            for (int x = 0; x < width; x++)
            {
                int k = 0;
                for (int dy = -maskBounds; dy <= maskBounds; dy++)
                {
                    int iy = y + dy;
                    if (0 <= iy && iy < height)
                    {
                        int ioffset = iy * width;
                        for (int dx = -maskBounds; dx <= maskBounds; dx++)
                        {
                            int ix = x + dx;
                            if (0 <= ix && ix < width)
                            {
                                int rgb = inPixels[ioffset + ix];
                                a[k] = (rgb >> 24) & 0xff;
                                r[k] = (rgb >> 16) & 0xff;
                                g[k] = (rgb >> 8) & 0xff;
                                b[k] = rgb & 0xff;
                                k++;
                            }
                        }
                    }
                }
                while (k < maskSize)
                {
                    a[k] = 0xff;
                    r[k] = g[k] = b[k] = 0;
                    k++;
                }
                outPixels[index++] = fullMedian(a, r, g, b);
            }
        }
        return outPixels;
    }
}

